package com.yuuzai.openworld.meter;

import java.util.Random;

import com.yuuzai.openworld.OpenWorldObject;
import com.yuuzai.openworld.framework.IUpdatable;

public class Meter extends OpenWorldObject implements IUpdatable, Comparable<Meter> {
	
	public void setDelta(long value) {
		this.setValue(this.getValue() + value);
	}
	
	protected void fixValue() {
		this.setValue(this.getValue());
	}
	
	public boolean isFull() {
		return this.getValue() >= this.getMaximum();
	}
	
	public void update() {
		this.update(now());
	}
	
	public void update(long t) {
		this.setDelta(this.getIncrement());
	}
	
	public void randomizeValue() {
		long min = this.getMinimum();
		long max = this.getMaximum();
		long value;
		
		Random r = new Random();
		value = min + (r.nextLong() % ((max - min) + 1));
		this.setValue(value);
	}
	
	public double getPercentage() {
		long min = this.getMinimum();
		long max = this.getMaximum();
		long value = this.getValue();
		
		max = max - min;
		if (max <= 0) {
			max = 1;
		}
		return (value - min) / max;
	}
	
	/* Definition */
	
	public static final long DEFAULT_MINIMUM = 0;
	public static final long DEFAULT_MAXIMUM = 100;
	public static final long DEFAULT_INCREMENT = 1;
	
	protected long current;
	protected long minimum;
	protected long maximum;
	protected long increment;
	protected boolean unlimited;
	
	public void setValue(long value) {
		long min = this.getMinimum();
		long max = this.getMaximum();
		
		if (value < min) {
			this.current = min;
		} else if(!this.getUnlimited() && value > max) {
			this.current = max;
		} else {
			this.current = value;
		}
	}
	
	public long getValue() {
		return this.current;
	}

	public void setMinimum(long value) {
		long max = this.getMaximum();
		this.minimum = (!this.getUnlimited() && value > max) ? max : value;
		this.fixValue();
	}
	
	public long getMinimum() {
		return this.minimum;
	}

	public void setMaximum(long value) {
		long min = this.getMinimum();
		this.maximum = (value < min) ? min : value;
		this.fixValue();
	}
	
	public long getMaximum() {
		return this.maximum;
	}
	
	public void setIncrement(long value) {
		this.increment = value;
	}

	public long getIncrement() {
		return this.increment;
	}

	public void setUnlimited(boolean value) {
		this.unlimited = value;
	}
	
	public boolean getUnlimited() {
		return this.unlimited;
	}

	public Meter() {
		this(DEFAULT_MINIMUM, DEFAULT_MAXIMUM);
	}
	
	public Meter(long min, long max) {
		this.setMinimum(min);
		this.setMaximum(max);
		this.setValue(max);
		this.setIncrement(DEFAULT_INCREMENT);
		this.setUnlimited(false);
	}

	/* Comparable */
	
	public int compareTo(Meter arg0) {
		return 0;
	}

}
